package io.renren.modules.file.service;

import io.renren.modules.file.config.FileProperties;
import io.renren.modules.file.entity.FileEntity;
import io.renren.modules.file.exception.FileException;
import io.renren.modules.oss.cloud.OSSFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.FileUrlResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

@Service
public class FileUploadService {
    private  FileProperties fileProperties; // 文件在本地存储的地址

    @Autowired
    private FileService fileService;

    @Autowired
    public FileUploadService(FileProperties fileProperties) {
        this.fileProperties = fileProperties;
    }

    /**
     * 存储文件到系统
     *
     * @param file 文件
     * @param lx 类型
     * @return 文件名
     */
    @Transactional(rollbackFor = Exception.class)
    public FileEntity storeFile(MultipartFile file, String lx) {
        if(StringUtils.isEmpty(lx)) {
            lx = "default";
        }

        String oriFileName = StringUtils.cleanPath(file.getOriginalFilename());
        String _fileName = oriFileName.substring(0, oriFileName.lastIndexOf("."));
        String suffix = oriFileName.substring(oriFileName.lastIndexOf(".") + 1);

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date date1 = new Date();
        String currentTime = lx + File.separatorChar + dateFormat.format(date1) ;
        String fileName = _fileName + "_" + date1.getTime() + "." + suffix;

        // 目录
        String dir = fileProperties.getUploadDir() + File.separatorChar + currentTime;
        // 绝对路径
        String absPath = dir + File.separatorChar + fileName;
        // 相对路径
        String realPath = File.separatorChar + currentTime + File.separatorChar + fileName;

        Path targetLocation = Paths.get(absPath);

        if(!Files.exists(Paths.get(dir))) {
            try {
                Files.createDirectories(targetLocation);
            } catch (Exception ex) {
                throw new FileException("Could not create the directory where the uploaded files will be stored.", ex);
            }
        }

        FileEntity fileEntity = new FileEntity();
        fileEntity.setFileName(fileName);
        fileEntity.setOriFileName(oriFileName);
        fileEntity.setFileType(file.getContentType());
        fileEntity.setSuffix(suffix);
        fileEntity.setXtlx(lx);
        fileEntity.setUrl(realPath);
        fileEntity.setSize(file.getSize());
        fileEntity.setCreateTime(date1);

        try {
            // Check if the file's name contains invalid characters
            if(fileName.contains("..")) {
                throw new FileException("Sorry! Filename contains invalid path sequence " + fileName);
            }

            // Copy file to the target location (Replacing existing file with the same name)
            Files.copy(file.getInputStream(), targetLocation, StandardCopyOption.REPLACE_EXISTING);
            fileService.save(fileEntity);

            return fileEntity;
        } catch (IOException ex) {
            ex.printStackTrace();
            throw new FileException("Could not store file " + fileName + ". Please try again!", ex);
        }
    }

    /**
     * 加载文件
     * @param id
     * @return
     */
    public Resource loadFileAsResource(Integer id) {
        FileEntity fileEntity = fileService.getById(id);
        String filePath = this.fileProperties.getUploadDir() + fileEntity.getUrl();
        try {
            Resource resource = null;
            if(fileEntity.getUrl().contains("http")) {
                filePath = fileEntity.getUrl();
                resource = new FileUrlResource(filePath);
            } else {
                resource = new FileSystemResource(filePath);
            }

            if(resource.exists()) {
                return resource;
            } else {
                throw new FileException("File not found " + filePath);
            }
        } catch (Exception ex) {
            throw new FileException("File not found " + filePath, ex);
        }
    }

    /**
     * 传fileEntity获取
     * @param fileEntity
     * @return
     */
    public Resource loadFileAsResource(FileEntity fileEntity) {
        return this.loadFileAsResource(fileEntity.getId());
    }

    public void deletFile(FileEntity entity) {
        String filePath = this.fileProperties.getUploadDir() + entity.getUrl();
        File file = new File(filePath);
        if(file.exists()) {
            file.delete();
        }
    }

    /**
     * 上传文件到OSS
     * @param file
     * @param xtlx
     * @return
     */
    public FileEntity storeOssFile(MultipartFile file, String xtlx) throws IOException {
        String oriFileName = StringUtils.cleanPath(file.getOriginalFilename());
        String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
        String url = OSSFactory.build().uploadSuffix(file.getBytes(), xtlx, suffix);

        Date date1 = new Date();

        FileEntity fileEntity = new FileEntity();
        fileEntity.setFileName(oriFileName);
        fileEntity.setOriFileName(oriFileName);
        fileEntity.setFileType(file.getContentType());
        fileEntity.setSuffix(suffix);
        fileEntity.setXtlx(xtlx);
        fileEntity.setUrl(url);
        fileEntity.setSize(file.getSize());
        fileEntity.setCreateTime(date1);

        fileService.save(fileEntity);

        return fileEntity;
    }
}
